package de.gof.ppstool.core.produktion.ui;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIData;
import javax.faces.event.ValueChangeEvent;
import org.springframework.aop.target.dynamic.Refreshable;
import de.gof.ppstool.core.produktion.LosplanungNewDeineMudda;
import de.gof.ppstool.fertigungsverwaltung.IFertigungsverwaltung;
import de.gof.ppstool.fertigungsverwaltung.db.Fertigungsauftrag;
import de.gof.ppstool.fertigungsverwaltung.db.FertigungsauftragNotFoundException;
import de.gof.ppstool.fertigungsverwaltung.db.Fertigungsauftragsposition;
import de.gof.ppstool.staticdata.IStaticDataVerwaltung;
import de.gof.ppstool.staticdata.StaticDataNotFoundException;
import de.gof.ppstool.util.GOFException;
import de.gof.ppstool.util.export.Output;
import de.gof.ppstool.util.export.ProductionItem;

@ManagedBean(name = LosplanungControllerBean.NAME)
@SessionScoped
public class LosplanungControllerBean implements Serializable {
	public static final String NAME = "lp";
	private static final long serialVersionUID = -5142035743414586001L;
	private Output output = Output.getInstance();
	private Fertigungsauftrag fertigungsauftrag;
	private String periode;
	private ProductionItem newProductionItem = new ProductionItem();
	private ProductionItem selectItem;
	private List<ProductionItem> verfuegbarItems = null;
	private List<ProductionItem> berechnet = new ArrayList<ProductionItem>();
	private List<ProductionItem> ausgewaehlteItemsManual = new ArrayList<ProductionItem>();
	private List<Fertigungsauftragsposition> fertigungsauftragspositionen;
	private List<ProductionItem> productionItems;
	private List<ProductionItem> nochOffen = new ArrayList<ProductionItem>();
	private List<ProductionItem> orderedList = null;
	@ManagedProperty(value = "#{" + IFertigungsverwaltung.NAME + "}")
	private IFertigungsverwaltung fv;
	@ManagedProperty(value = "#{" + IStaticDataVerwaltung.NAME + "}")
	private IStaticDataVerwaltung sdv;
	@ManagedProperty(value = "#{" + LosplanungNewDeineMudda.NAME + "}")
	private LosplanungNewDeineMudda lp;
	final String JSF_LOSPLANUNG = "/losplanung/losplanung";
	final String JSF_NO_XMLINPUT = "/produktionsprogramm/invalid";
	final String JSF_PRODUKTIONSPLAN_NOT_FOUND = "/produktionsprogramm/produktionsplan_not_found";
	final String JSF_OK_LOSPLANUNG = "/losplanung/okLP";
	private UIData orderingList;
	private UIData tabelleDataTable;

	public void newProductionItemMethod() {
		if ((newProductionItem.getArticleId() != null)
				&& (newProductionItem.getArticleId() > 0)) {
			if ((newProductionItem.getQuantity() != null)
					&& (newProductionItem.getQuantity() > 0)) {
				List<ProductionItem> productionItems = (List<ProductionItem>) orderingList
						.getValue();
				if (productionItems.size() > 1) {
					//productionItems.add(newProductionItem);
					verfuegbarItems.add(newProductionItem);
					orderingList.setValue(null);
					orderingList.setValue(verfuegbarItems);
					newProductionItem = new ProductionItem();
				}

			}

		}

	}

	public void deleteItem() {
		Integer index = orderingList.getRowIndex();
		if (index != -1) {
			List<ProductionItem> productionItems = (List<ProductionItem>) orderingList
					.getValue();
			ProductionItem pi = verfuegbarItems.get(index);
			Boolean geloescht = verfuegbarItems.remove(pi);
			if (geloescht) {
				orderingList.setValue(null);
				orderingList.setValue(verfuegbarItems);
			}

		}

	}

	public void changeItem(ValueChangeEvent e) {
		Integer index = orderingList.getRowIndex();
		if (index != -1) {
			List<ProductionItem> productionItems = (List<ProductionItem>) orderingList
					.getValue();
			ProductionItem pi = productionItems.get(index);
			pi.setQuantity((Integer) e.getNewValue());
			verfuegbarItems.set(index, pi);
			if (!e.getNewValue().equals(e.getOldValue())) {
				Integer sum = (Integer) e.getNewValue()
						- (Integer) e.getOldValue();
				ProductionItem piNeu = new ProductionItem(pi.getArticleId(),
						sum);
				Boolean add = true;
				if (nochOffen.size() > 0) {
					for (ProductionItem piOffen : nochOffen) {
						// Ueberpruefen ob der Artikle schonmal in der Tabelle vorkommt
						// Wenn ja dann verrechnen und die Tabelle anpassen
						if (piNeu.getArticleId().equals(piOffen.getArticleId())) {
							Integer sum1 = piOffen.getQuantity()
									+ piNeu.getQuantity();
							piOffen.setQuantity(sum1);
							if (sum1.equals(0))
								nochOffen.remove(piOffen);

							add = false;
							break;
						}

					}
				}

				if (add)
					nochOffen.add(piNeu);

			}

		}

	}

	//TODO neue Reihenfolge festhalten fuer Losplanung
	public String saveLosplanung() {
		Object o = orderingList.getValue();
		List<ProductionItem> liste = (List<ProductionItem>) o;
		output.setProduktionsliste(null);
		output.setProduktionsliste(verfuegbarItems);
		return JSF_OK_LOSPLANUNG;
	}

	public String ermittleLosplanung() {
		try {
			periode = sdv.getCurrentPeriod();
		} catch (StaticDataNotFoundException e) {
		}

		if (periode.equals(new String("-1")))
			return JSF_NO_XMLINPUT;

		try {
			fertigungsauftrag = fv.findeFertigungsauftragNachBemerkung(periode);
			fertigungsauftragspositionen = fertigungsauftrag
					.getFertigungsauftragspositionen();
		} catch (FertigungsauftragNotFoundException e) {
			return JSF_PRODUKTIONSPLAN_NOT_FOUND;
		}

		List<Fertigungsauftrag> fertigungsauftrage = new ArrayList<Fertigungsauftrag>();
		fertigungsauftrage.add(fertigungsauftrag);
		try {
			lp.ermittleReihenfolge(fertigungsauftrage, periode);
		} catch (GOFException e) {
		}

		verfuegbarItems = (ArrayList<ProductionItem>) output
				.getProduktionsliste();
		return JSF_LOSPLANUNG;
	}

	public IStaticDataVerwaltung getSdv() {
		return sdv;
	}

	public void setSdv(IStaticDataVerwaltung sdv) {
		this.sdv = sdv;
	}

	public IFertigungsverwaltung getFv() {
		return fv;
	}

	public void setFv(IFertigungsverwaltung fv) {
		this.fv = fv;
	}

	public LosplanungNewDeineMudda getLp() {
		return lp;
	}

	public void setLp(LosplanungNewDeineMudda lp) {
		this.lp = lp;
	}

	public UIData getTabelleDataTable() {
		return tabelleDataTable;
	}

	public void setTabelleDataTable(UIData tabelleDataTable) {
		this.tabelleDataTable = tabelleDataTable;
	}

	public List<ProductionItem> getProductionItems() {
		return productionItems;
	}

	public void setProductionItems(List<ProductionItem> productionItems) {
		this.productionItems = productionItems;
	}

	public List<ProductionItem> getVerfuegbarItems() {
		if (verfuegbarItems == null)
			ermittleLosplanung();

		return verfuegbarItems;
	}

	public void setVerfuegbarItems(List<ProductionItem> verfuegbarItems) {
		this.verfuegbarItems = verfuegbarItems;
	}

	public Fertigungsauftrag getFertigungsauftrag() {
		return fertigungsauftrag;
	}

	public void setFertigungsauftrag(Fertigungsauftrag fertigungsauftrag) {
		this.fertigungsauftrag = fertigungsauftrag;
	}

	public String getPeriode() {
		return periode;
	}

	public void setPeriode(String periode) {
		this.periode = periode;
	}

	public List<Fertigungsauftragsposition> getFertigungsauftragspositionen() {
		return fertigungsauftragspositionen;
	}

	public void setFertigungsauftragspositionen(
			List<Fertigungsauftragsposition> fertigungsauftragspositionen) {
		this.fertigungsauftragspositionen = fertigungsauftragspositionen;
	}

	public List<ProductionItem> getNochOffen() {
		return nochOffen;
	}

	public void setNochOffen(List<ProductionItem> nochOffen) {
		this.nochOffen = nochOffen;
	}

	public List<ProductionItem> getAusgewaehlteItemsManual() {
		return ausgewaehlteItemsManual;
	}

	public void setAusgewaehlteItemsManual(
			List<ProductionItem> ausgewaehlteItemsManual) {
		this.ausgewaehlteItemsManual = ausgewaehlteItemsManual;
	}

	public List<ProductionItem> getAusgewaehlt() {
		return berechnet;
	}

	public void setAusgewaehlt(List<ProductionItem> ausgewaehlt) {
		this.berechnet = ausgewaehlt;
	}

	public UIData getOrderingList() {
		return orderingList;
	}

	public void setOrderingList(UIData orderingList) {
		this.orderingList = orderingList;
	}

	public ProductionItem getNewProductionItem() {
		return newProductionItem;
	}

	public void setNewProductionItem(ProductionItem newProductionItem) {
		this.newProductionItem = newProductionItem;
	}

	public ProductionItem getSelectItem() {
		return selectItem;
	}

	public void setSelectItem(ProductionItem selectItem) {
		this.selectItem = selectItem;
	}

	public List<ProductionItem> getOrderedList() {
		return orderedList;
	}

	public void setOrderedList(List<ProductionItem> orderedList) {
		this.orderedList = orderedList;
	}

}
